﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sunny.Controls.Searcher
{
	public class AdvanceSearcher : Table
	{
		protected readonly System.Collections.Generic.IEnumerable<SearchItem> SearchItems;

		public void Save(string filePath)
		{
			this.Save(System.IO.File.OpenWrite(filePath));
		}

		public void Save(System.IO.Stream stream)
		{
			System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream);
			System.Collections.Generic.IEnumerable<TableRow> rows = this.Rows.Skip(1).OfType<TableRow>();
			writer.Write(rows.Count());
			foreach (TableRow row in rows)
			{
				for (int i = 0; i < 7; i++)
				{
					if (i == 4)
						continue;
					writer.Write((string)((System.Windows.Controls.Primitives.Selector)row.Cells[i].Content).SelectedValue);
				}
				new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(stream, row.SelectedSearchItem.GetInputValue((System.Windows.FrameworkElement)row.InputControl));
			}
			writer.Close();
		}

		public void Open(string filePath)
		{
			this.Open(System.IO.File.OpenRead(filePath));
		}

		public void Open(System.IO.Stream stream)
		{
			while (this.Rows.Count != 1)
				this.Rows.RemoveAt(1);

			System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);
			System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
			int rowsCount = reader.ReadInt32();
			for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++)
			{
				TableRow row = this.CreateRow();
				for (int columnIndex = 0; columnIndex < row.Cells.Count; columnIndex++)
				{
					if (columnIndex == 4)
						continue;
					string value = reader.ReadString();
					Telerik.Windows.Controls.RadComboBox dropDownList = (Telerik.Windows.Controls.RadComboBox)row.Cells[columnIndex].Content;
					/*if (columnIndex == 3)
						dropDownList.DataSource = value;
					else */dropDownList.SelectedValue = value;
				}

				row.SelectedSearchItem.SetInputValue((System.Windows.FrameworkElement)row.Cells[4].Content, new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Deserialize(stream));


				this.Rows.Add(row);
			}
			reader.Close();
		}

		public AdvanceSearcher(System.Collections.Generic.IEnumerable<SearchItem> items)
		{
			//this.CellSpacing = 0;
			this.CellPadding = new System.Windows.Thickness(5);

			TableRow headerRow = new TableRow();
			headerRow.Cells.Add(new TableCell { Content = "连接" });
			headerRow.Cells.Add(new TableCell { Content = "左括号" });
			headerRow.Cells.Add(new TableCell { Content = "字段" });
			headerRow.Cells.Add(new TableCell { Content = "运算符" });
			headerRow.Cells.Add(new TableCell { Content = "内容" });
			headerRow.Cells.Add(new TableCell { Content = "右括号" });
			headerRow.Cells.Add(new TableCell { Content = "操作" });
			this.Rows.Add(headerRow);

			this.SearchItems = items;
		}

		protected class TableRow : Sunny.Controls.TableRow
		{
			public DropDownList<string, string> LinkList
			{
				get
				{
					return (DropDownList<string, string>)this.Cells[0].Content;
				}
			}

			public Telerik.Windows.Controls.RadComboBox LeftBracket
			{
				get
				{
					return (Telerik.Windows.Controls.RadComboBox)this.Cells[1].Content;
				}
			}

			public System.Windows.Controls.ComboBox FieldList
			{
				get
				{
					return (System.Windows.Controls.ComboBox)this.Cells[2].Content;
				}
			}

			public Telerik.Windows.Controls.RadComboBox OperatorList
			{
				get
				{
					return (Telerik.Windows.Controls.RadComboBox)this.Cells[3].Content;
				}
			}

			public TableCell InputCell
			{
				get
				{
					return this.Cells[4];
				}
			}

			public System.Windows.FrameworkElement InputControl
			{
				get
				{
					return (System.Windows.FrameworkElement)this.Cells[4].Content;
				}
			}

			public Telerik.Windows.Controls.RadComboBox RightBracket
			{
				get
				{
					return (Telerik.Windows.Controls.RadComboBox)this.Cells[5].Content;
				}
			}

			public Telerik.Windows.Controls.RadComboBox DeleteButton
			{
				get
				{
					return (Telerik.Windows.Controls.RadComboBox)this.Cells[5].Content;
				}
			}

			public SearchItem SelectedSearchItem
			{
				get
				{
					return ((AdvanceSearcher)this.Table).SearchItems.ElementAt(this.FieldList.SelectedIndex);
				}
			}
		}

		//public AdvanceSearcher(SearchItem[] items)
		//{
		//    foreach (SearchItem item in items)
		//    {
		//    }
		//}

		protected TableRow CreateRow()
		{
			TableRow row = new TableRow();

			TableCell cell = new TableCell();
			DropDownList<string, string> linkList = new DropDownList<string, string>();
			if (this.Rows.Count <= 1)
				linkList.Visibility = System.Windows.Visibility.Hidden;
			//linkList.Width = 40;
			linkList.AddItem("且", "&&");
			linkList.AddItem("或", "||");
			linkList.SelectedIndex = 0;
			cell.Content = linkList;
			row.Cells.Add(cell);

			cell = new TableCell();
			Telerik.Windows.Controls.RadComboBox leftBracket = new Telerik.Windows.Controls.RadComboBox();
			leftBracket.Items.Add("");
			leftBracket.Items.Add("(");
			cell.Content = leftBracket;
			row.Cells.Add(cell);

			cell = new TableCell();
			System.Windows.Controls.ComboBox fieldList = new System.Windows.Controls.ComboBox();
			fieldList.DisplayMemberPath = "Title";
			fieldList.SelectedValuePath = "Field";
			fieldList.ItemsSource = this.SearchItems;
			fieldList.Items.Filter = i => ((SearchItem)i).ShowInAdvanceSearcher;
			fieldList.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(FieldList_SelectionChanged);
			cell.Content = fieldList;
			row.Cells.Add(cell);

			cell = new TableCell();
			Telerik.Windows.Controls.RadComboBox operatorList = new Telerik.Windows.Controls.RadComboBox();
			//foreach (Operator itemOperator in this.SearchItems.First().Operators)
			//    operatorList.Items.Add(new Telerik.Web.UI.DropDownListItem(itemOperator.Name, itemOperator.Expression));
			cell.Content = operatorList;
			row.Cells.Add(cell);

			cell = new TableCell();
			//cell.Controls.Add(this.SearchItems.First().AdvanceSearcherInput);
			row.Cells.Add(cell);

			cell = new TableCell();
			Telerik.Windows.Controls.RadComboBox rightBracket = new Telerik.Windows.Controls.RadComboBox();
			rightBracket.Items.Add("");
			rightBracket.Items.Add(")");
			cell.Content = rightBracket;
			row.Cells.Add(cell);

			cell = new TableCell();
			Sunny.Controls.Button button = new Sunny.Controls.Button();
			button.Icon = (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom("pack://application:,,,/Sunny.Controls;component/Toolbar/Images/Clear.png");
			button.Text = "删除";
			button.Click += new System.Windows.RoutedEventHandler(Delete_Click);
			cell.Content = button;
			row.Cells.Add(cell);

			fieldList.SelectedIndex = 0;
			return row;
		}

		public void AddRow()
		{
			this.Rows.Add(this.CreateRow());
		}

		void FieldList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
		{
			TableRow row = (TableRow)((TableCell)((System.Windows.Controls.ComboBox)sender).Parent).Row;
			SearchItem searchItem = this.SearchItems.ElementAt(row.FieldList.SelectedIndex);
			row.OperatorList.DisplayMemberPath = "Name";
			row.OperatorList.SelectedValuePath = "Expression";
			row.OperatorList.ItemsSource = searchItem.Operators;

			row.InputCell.Content = searchItem.AdvanceSearcherInput;
		}

		void Delete_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			TableRow row = (TableRow)((TableCell)((Sunny.Controls.Button)sender).Parent).Row;
			Table table = row.Table;
			int index = table.Rows.IndexOf(row);
			table.Rows.RemoveAt(index);
			if (index == 1)
				if (table.Rows.Count > 1)
					((TableRow)table.Rows[1]).LinkList.Visibility = System.Windows.Visibility.Hidden;
		}

		private WhereCommand _WhereCommand;
		public WhereCommand WhereCommand
		{
			get
			{
				if (this.Rows.Count == 1)
					return null;
				if (this._WhereCommand == null)
				{
					string command = null;
					System.Collections.ArrayList parameters = new System.Collections.ArrayList();
					for (int i = 1; i < this.Rows.Count; i++)
					{
						TableRow row = (TableRow)this.Rows[i];

							if (i > 1)
								command += row.LinkList.SelectedValue;
							command += row.LeftBracket.SelectedItem;

							if (row.SelectedSearchItem.Fields.Length > 1)
								command += "(";
							for (int j = 0; j < row.SelectedSearchItem.Fields.Length; j++)
							{
								string field = row.SelectedSearchItem.Fields[j];
								WhereCommand whereCommand = row.SelectedSearchItem.GetCommand(field, (string)row.FieldList.SelectedValue, parameters.Count, row.InputControl);
								parameters.AddRange(whereCommand.Parameters);
								if (whereCommand == null)
									continue;

								if (j != 0)
									command += "||";
								//command += string.Format(((Telerik.Web.UI.RadDropDownList)cells[3].Controls[0]).SelectedValue, searchItem.Field, "@" + (i - 1));
								command += whereCommand.Text;

							}

							if (row.SelectedSearchItem.Fields.Length > 1)
								command += ")";

							command += row.RightBracket.SelectedItem;
					}
					this._WhereCommand = new WhereCommand { Text = command, Parameters = parameters.ToArray() };
				}
				return this._WhereCommand;
			}
		}
	}
}